#ifndef __INKLUDE_I_NETWORK_CLIENT_H__
#define __INKLUDE_I_NETWORK_CLIENT_H__

#include <memory>
#include <functional>

namespace Inklude
{
    /*!
    * @brief  This is a virtual class that has only 4 methods.
    *         Eacy type of connection is implemented accordingly.
    * @author Seokhwan Kim, IPLAB, Dept. of CS., Univ. of Tsukuba
    * @date   Nov, 2011
    * @remark You can refer ikCTcpClient.h and ikCUdpClient.h classes for specific implementation.
    */ 
    class INKLUDE_CLASS_EXPORT ikINetClient
    {
    public:
        /*!
        * @brief AsyncHandler is used when it is used in asynchronous way.
        */
        typedef std::shared_ptr<std::function<void (size_t)> > AsyncHandler;

        /*!
        * @brief constructor
        */
        ikINetClient() {}

        /*!
        * @brief Destructor
        */
        virtual ~ikINetClient() {}

        /*!
        * @brief     It returns an instance of connection you want to create.
        * @param[in] nRecvPort this port is used when this connection receives data.
        * @return    void
        */
        virtual void Initialize(unsigned int nRecvPort = 0) = 0;

        /*!
        * @brief     It returns an instance of connection you want to create.
        * @param[in] IPAddress Address of destination host. e.g., "192.100.80.88", "localhost", or some_domain_name.
        * @param[in] nPort Port of socket of destination socket.
        * @return    void
        */
        virtual void SetDestinationAddress(const char* IPAddress, unsigned int nPort) = 0;

        /*!
        * @brief     It sends the data in pBuffer as much as described in nDataSize
        *            If AsyncHandler is given, it works in async way. Otherwise, it works in synchronized way.
        * @param[in] pBuffer start point of buffer you want to send.
        * @param[in] nDataSize the size of data you want to send.
        * @param[in] endHandler Handler for asynchronous call. When the data is sent, this handler is called automatically.
        * @return    size_t It returns the size of sent data.
        */
        virtual size_t Send(const void* pBuffer, size_t nDataSize, AsyncHandler endHandler = NULL) = 0;

        /*!
        * @brief     It receives the data in pBuffer as much as described in nDataSize
        *            If AsyncHandler is given, it works in async way. Otherwise, it works in synchronized way.
        * @param[in] pBuffer start point of buffer you want to receive.
        * @param[in] nDataSize the size of data you want to receive.
        * @param[in] endHandler Handler for asynchronous call. When the data is received, this handler is called automatically.
        * @return    size_t It returns the size of received data.
        */
        virtual size_t Receive(void* pBuffer, const size_t nDataSize, AsyncHandler endHandler = NULL) = 0;

        /*!
        * @brief     It closes the connection.
        * @return    void
        */
        virtual void Close() = 0;
    };
}

#endif // __INKLUDE_C_NETWORK_CLIENT_H__

